home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / SOURCES / GRAPHIC / RASTERRE.C < prev    next >
C/C++ Source or Header  |  1991-12-11  |  6KB  |  235 lines

  1. /*
  2.  * Copyright (c) 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * Implementation of RasterRect, an object derived from Graphic.
  25.  */
  26.  
  27. #include <InterViews/raster.h>
  28. #include <InterViews/transformer.h>
  29. #include <InterViews/Graphic/grclasses.h>
  30. #include <InterViews/Graphic/rasterrect.h>
  31.  
  32. /*****************************************************************************/
  33.  
  34. class ColorMaker {
  35. public:
  36.     ColorMaker();
  37.     ~ColorMaker();
  38.     Color* MakeColor(ColorIntensity r, ColorIntensity g, ColorIntensity b);
  39. private:
  40.     int size;
  41.     Color** colors;
  42.     void Grow(int size);
  43. };
  44.  
  45. ColorMaker::ColorMaker () {
  46.     size = 0;
  47.     colors = nil;
  48.     Grow(256);
  49. }
  50.  
  51. ColorMaker::~ColorMaker () {
  52.     for (int i = 0; i < size; ++i) {
  53.     Unref(colors[i]);
  54.     }
  55.     delete colors;
  56. }
  57.  
  58. void ColorMaker::Grow (int s) {
  59.     Color** newcolors = new Color*[s];
  60.     for (int i = 0; i < s; ++i) {
  61.         if (i < size) {
  62.             newcolors[i] = colors[i];
  63.         } else {
  64.             newcolors[i] = nil;
  65.         }
  66.     }
  67.     delete colors;
  68.     colors = newcolors;
  69.     size = s;
  70. }
  71.  
  72. Color* ColorMaker::MakeColor (
  73.     ColorIntensity r, ColorIntensity g, ColorIntensity b
  74. ) {
  75.     int hash = (r + g + b) % size;
  76.     for (int i = 0; i < 256; ++i) {
  77.         int index = (i + hash) % size;
  78.         if (colors[index] != nil) {
  79.             ColorIntensity rr, gg, bb;
  80.             colors[index]->Intensities(rr, gg, bb);
  81.             if (rr == r && gg == g && bb == b) {
  82.                 return colors[index];
  83.             } else {
  84.                 i = (i+1) % size;
  85.             }
  86.         } else {
  87.         Color* c = new Color(r, g, b);
  88.         c->Reference();
  89.             colors[index] = c;
  90.             return c;
  91.         }
  92.     }
  93.     Grow(size*2);
  94.     return MakeColor(r, g, b);
  95. }
  96.  
  97. /*****************************************************************************/
  98.  
  99. ColorMaker* RasterRect::colorMaker;
  100.  
  101. void RasterRect::draw (Canvas *c, Graphic* gs) {
  102.     update(gs);
  103.     pRasterRect(c, 0, 0, raster);
  104. }
  105.  
  106. ClassId RasterRect::GetClassId () { return _RASTERRECT; }
  107.  
  108. boolean RasterRect::IsA (ClassId id) { 
  109.     return _RASTERRECT == id || Graphic::IsA(id);
  110. }
  111.  
  112. void RasterRect::Init () {
  113.     if (colorMaker == nil) {
  114.         colorMaker = new ColorMaker;
  115.     }
  116. }
  117.  
  118. RasterRect::RasterRect () { 
  119.     Init();
  120.     raster = nil;
  121. }
  122.  
  123. RasterRect::RasterRect (Raster* r, Graphic* gr) : (gr) {
  124.     Init();
  125.     raster = r;
  126.     raster->Reference();
  127. }
  128.  
  129. Graphic* RasterRect::Copy () {
  130.     return new RasterRect(new Raster(raster), this);
  131. }
  132.  
  133. RasterRect::~RasterRect () {
  134.     Unref(raster);
  135. }
  136.  
  137. Raster* RasterRect::GetOriginal () { return raster; }
  138.  
  139. boolean RasterRect::readRaster (PFile* f, Raster*& raster) {
  140.     int w, h;
  141.     ColorIntensity r, g, b;
  142.     boolean ok = f->Read(w) && f->Read(h);
  143.  
  144.     if (ok) {
  145.         raster = new Raster(nil, w, h);
  146.     raster->Reference();
  147.  
  148.         for (int i = 0; i < w; ++i) {
  149.             for (int j = 0; j < h && ok; ++j) {
  150.         ok = f->Read((int)r) && f->Read((int)g) && f->Read((int)b);
  151.         raster->Poke(colorMaker->MakeColor(r, g, b), i, j);
  152.         }
  153.     }
  154.     }
  155.     return ok;
  156. }
  157.  
  158. boolean RasterRect::writeRaster (PFile* f, Raster* raster) {
  159.     int w = raster->Width();
  160.     int h = raster->Height();
  161.     ColorIntensity r, g, b;
  162.     boolean ok = f->Write(w) && f->Write(h);
  163.  
  164.     if (ok) {
  165.     for (int i = 0; i < w; ++i) {
  166.         for (int j = 0; j < h && ok; ++j) {
  167.         raster->Peek(i, j)->Intensities(r, g, b);
  168.         ok = f->Write((int)r) && f->Write((int)g) && f->Write((int)b);
  169.             }
  170.         }
  171.     }
  172.     return ok;
  173. }
  174.  
  175. boolean RasterRect::read (PFile* f) {
  176.     return Graphic::read(f) && readRaster(f, raster);
  177. }
  178.  
  179. boolean RasterRect::write (PFile* f) {
  180.     return Graphic::write(f) && writeRaster(f, raster);
  181. }
  182.  
  183. void RasterRect::getExtent (
  184.     float& x0, float& y0, float& cx, float& cy, float& tol, Graphic* gs
  185. ) {
  186.     if (gs->GetTransformer() == nil) {
  187.     x0 = y0 = 0;
  188.     cx = raster->Width() / 2;
  189.     cy = raster->Height() / 2;
  190.     } else {
  191.     transformRect(0,0,raster->Width(),raster->Height(),x0,y0,cx,cy,gs);
  192.     cx = (cx + x0)/2;
  193.     cy = (cy + y0)/2;
  194.     }
  195.     tol = 0;
  196. }
  197.  
  198. boolean RasterRect::contains (PointObj& po, Graphic* gs) {
  199.     PointObj pt (&po);
  200.     invTransform(pt.x, pt.y, gs);
  201.     BoxObj b (0, 0, raster->Width(), raster->Height());
  202.     return b.Contains(pt);
  203. }
  204.  
  205. boolean RasterRect::intersects (BoxObj& userb, Graphic* gs) {
  206.     Transformer* t = gs->GetTransformer();
  207.     Coord xmax = raster->Width();
  208.     Coord ymax = raster->Height();
  209.     Coord tx0, ty0, tx1, ty1;
  210.     
  211.     if (t != nil && t->Rotated()) {
  212.     Coord x[4], tx[5];
  213.     Coord y[4], ty[5];
  214.     
  215.     x[0] = x[3] = y[0] = y[1] = 0;
  216.     x[2] = x[1] = xmax;
  217.     y[2] = y[3] = ymax;
  218.     transformList(x, y, 4, tx, ty, gs);
  219.     tx[4] = tx[0];
  220.     ty[4] = ty[0];
  221.     FillPolygonObj fp (tx, ty, 5);
  222.     return fp.Intersects(userb);
  223.     
  224.     } else if (t != nil) {
  225.     t->Transform(0, 0, tx0, ty0);
  226.     t->Transform(xmax, ymax, tx1, ty1);
  227.     BoxObj b1 (tx0, ty0, tx1, ty1);
  228.     return b1.Intersects(userb);
  229.  
  230.     } else {
  231.     BoxObj b2 (0, 0, xmax, ymax);
  232.     return b2.Intersects(userb);
  233.     }
  234. }
  235.